package com.eryos.android.cigarettecounter;

/**
 * Project :  CigaretteCounter
 * Author :   Olivier Combe 
 * URL :      http://eryos.fr/CigaretteCounter/
 *
 * Copyright (C) 2011 - Olivier Combe 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 */

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.TextView;

import com.eryos.android.cigarettecounter.beans.History;
import com.eryos.android.cigarettecounter.beans.SmokeAverage;
import com.eryos.android.cigarettecounter.beans.SmokeCounter;
import com.eryos.android.cigarettecounter.charts.Chart;
import com.eryos.android.cigarettecounter.charts.HistoChart;
import com.eryos.android.cigarettecounter.charts.LineChart;
import com.eryos.android.cigarettecounter.database.CigaretteDatabase;
import com.eryos.android.cigarettecounter.ui.ChartPopup;

public class HistoryActivity extends RootActivity {

    /** *************** UI Elements *************** **/	
    private TextView averageLabel;
    private TextView totalLabel;
    private TextView costLabel;
    private TextView historyTitle;
    private TextView chartTitle;
    private Gallery gCharts;
    private ImageAdapter ia;
    
    private Button homeButton; 
    private Button showStatButton; 
    
    /** *************** Instance Variables *************** **/	
    private History type;

    private int SCREEN_WIDTH = 320;
    
    private int OVERVIEW_WIDTH 	= 320;
    private int OVERVIEW_HEIGHT = 200;
    private int CHART_WIDTH 	= 320;
    private int CHART_HEIGHT 	= 200;
    
    private double CHART_RATIO = 0.625;

    private ArrayList<SmokeCounter> countValues;
    private ArrayList<SmokeAverage> averageValues;

    private String chartOverviewURL[] = new String[2];
    private String chartImageURL[] 	  = new String[2];
    private Bitmap[] thumbsTab = new Bitmap[2];
    private String[] titlesTab;

    private double 	average = -1;
    private double 	cost = -1;
    private int 	total = -1;
	
    private String detailChartData			= "";
    private String detailChartLabel			= "";
    private int    detailsMaxValue			= -1;
	
    private String histoChartData			= "";
    private String histoChartLabel			= "";
    private double histoMaxValue			= -1;
    
	/* ********************************************************************** */
	/*                  REAL     METHODS                                      */
	/* ********************************************************************** */

	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        thumbsTab = new Bitmap[2];
        titlesTab = new String[2];

        // Show charts
        if ( type.isWeekly() ){
        	showStatButton.setText(getResources().getString(R.string.home_month_stat_button_label));
            showWeeklyDetailChart();
            showWeeklyHistoryChart();        	
        }else if(type.isMonthly()){
        	showStatButton.setText(getResources().getString(R.string.home_week_stat_button_label));
            showMonthlyDetailChart();
            showMonthlyHistoryChart();        	
        }
    }

    /**
     * Method used to initialized all UI elements
     */
	protected void initUI(){
	    setContentView(R.layout.history);
	    	    
	    gCharts				= (Gallery) findViewById(R.id.history_charts_galery);
	    averageLabel 		= (TextView)findViewById(R.id.history_stats_average);
	    totalLabel 			= (TextView)findViewById(R.id.history_stats_total);
	    costLabel 			= (TextView)findViewById(R.id.history_stats_cost);
	    historyTitle		= (TextView)findViewById(R.id.history_stats_title);
	    chartTitle			= (TextView)findViewById(R.id.history_charts_title);
	    homeButton			= (Button)findViewById(R.id.history_home_button); 
	    showStatButton		= (Button)findViewById(R.id.history_other_button);

	    ia = new ImageAdapter(this);
	    gCharts.setAdapter(ia);
	    
	    defineHandlers(); 
	    
	    SCREEN_WIDTH = this.getWindow().getWindowManager().getDefaultDisplay().getWidth();
//	    SCREEN_HEIGHT = this.getWindow().getWindowManager().getDefaultDisplay().getHeight();
        
        if ( SCREEN_WIDTH < 400 ){
        	OVERVIEW_WIDTH = (int) (0.67 * SCREEN_WIDTH);
        	OVERVIEW_HEIGHT = (int) (CHART_RATIO * OVERVIEW_WIDTH);
        }

        CHART_WIDTH = (int) (0.95 * SCREEN_WIDTH);
    	CHART_HEIGHT = (int) (CHART_RATIO * CHART_WIDTH);

	}
	
	public void defineHandlers(){
        gCharts.setOnItemSelectedListener(new OnItemSelectedListener(){
			public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {
				chartTitle.setText(titlesTab[position]);
			}
			public void onNothingSelected(AdapterView<?> arg0) { }
        });
        
        gCharts.setOnItemClickListener(new OnItemClickListener() {
            @SuppressWarnings("rawtypes")
			public void onItemClick(AdapterView parent, View v, int position, long id) {
            	new ChartPopup(HistoryActivity.this, titlesTab[position],chartImageURL[position]);
            }
        });
        
        showStatButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                if ( type.isWeekly() ){
                	//launchMonthlyStats();
                	showView(VIEW.MONTHLY);
                }else if(type.isMonthly()){
                	//launchWeeklyStats();
                	showView(VIEW.WEEKLY);
                }
            }
        });
        
        homeButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
//            	launchHome();
            	showView(VIEW.HOME);
            }
        });
	}
		
	/**
	 * 
	 */
	protected void initValues(){
        countValues		= new ArrayList<SmokeCounter>();
        averageValues	= new ArrayList<SmokeAverage>();

        type = (History)this.getIntent().getExtras().getSerializable(History.class.toString());

        if ( type.isWeekly() ){
        	countValues 	= db.getWeeklyDetails();
        	average 		= db.getWeeklyAverage();
        	averageValues 	= db.getLastWeeksAverage();
        	cost 			= db.getWeeklyCost();
        	total 			= db.getWeeklyCount();
        	historyTitle.setText(R.string.history_weekly_title);
        }else if(type.isMonthly()){
        	countValues 	= db.getMonthlyDetails();
        	average 		= db.getMonthlyAverage();
        	averageValues 	= db.getLastMonthsAverage();
        	cost 			= db.getMonthlyCost();
        	total 			= db.getMonthlyCount();
        	historyTitle.setText(R.string.history_monthly_title);
        }
        
        
        String averageValueLabel = getResources().getString(R.string.history_average_label);    	
        averageLabel.setText("     "+averageValueLabel.replaceAll("#", average+""));

        String totalValueLabel = getResources().getString(R.string.history_total_label);    	
        totalLabel.setText("     "+totalValueLabel.replaceAll("#", total+""));
        
        String costValueLabel = getResources().getString(R.string.history_cost_label);
        NumberFormat ccyNF = NumberFormat.getCurrencyInstance(Locale.getDefault());
        costLabel.setText("     "+costValueLabel+" "+ccyNF.format(cost));
	}

	/**
	 * 
	 */
    protected void showMonthlyDetailChart(){
    	String lastDate = "";
    	int lastDayOfMonth = 31;
    	int i = 0;

    	if ( countValues.size() > 0 ){

    		SmokeCounter firstSmoke = countValues.get(0);
    		int first = firstSmoke.getDate().get(Calendar.DAY_OF_MONTH);
    		
    		lastDayOfMonth = CigaretteDatabase.getLastDayOfMonth(firstSmoke.getDate().get(Calendar.MONTH)-1);
    		
    		if ( first > 1 ){
    			for ( int y = 1 ; y < first; y++)
    	        	detailChartData = detailChartData + "0" + Chart.DATA_SEPARATOR;
    		}

        	for (SmokeCounter smoke : countValues){
        		i++;
            	lastDate = smoke.getLabel();
            	detailChartData = detailChartData + "" + smoke.getValue() + Chart.DATA_SEPARATOR;
            	if ( smoke.getValue() > detailsMaxValue )
            		detailsMaxValue = smoke.getValue();
        	}
        	i += first;
        	for ( int j = i ; j <= lastDayOfMonth ; j ++ )
            	detailChartData = detailChartData + "0" + Chart.DATA_SEPARATOR;

    	}

    	/* Create the chart and define all parameters */
    	LineChart lc = new LineChart();
        lc.setAvgLegend(getResources().getString(R.string.history_month_average_legend));
        lc.setValueLegend(getResources().getString(R.string.history_month_value_legend));
        lc.setMaxYValue(detailsMaxValue);
        lc.setMaxXValue(lastDayOfMonth);
        lc.setData(detailChartData); 
        lc.setAverage(average);
        
        titlesTab[0] = getResources().getString(R.string.history_month_detail_label)+" "+Chart.getMonthLabel(this, lastDate);

        /* Define the Thumb URL */
        lc.setWidth(OVERVIEW_WIDTH);
        lc.setHeight(OVERVIEW_HEIGHT);
        
        chartOverviewURL[0] = lc.getURL();

        /* Define the Chart URL */
        lc.setWidth(CHART_WIDTH);
        lc.setHeight(CHART_HEIGHT);
        
        chartImageURL[0] = lc.getURL();
    }
    
    protected void showMonthlyHistoryChart(){
    	
    	for (SmokeAverage smoke : averageValues){
    		histoChartData = histoChartData + "" + smoke.getValue() + Chart.DATA_SEPARATOR;
    		histoChartLabel = histoChartLabel + "" + Chart.getMonthFirstLetter(this, new Integer(smoke.getLabel()) ) + Chart.LABEL_SEPARATOR;
        	if ( smoke.getValue() > histoMaxValue )
        		histoMaxValue = smoke.getValue();
    	}
        
    	/* Create the chart and define all parameters */
    	HistoChart hst = new HistoChart();
    	hst.setYAxisLabel(histoChartLabel); 
        hst.setData(histoChartData);
        hst.setMaxVal( new BigDecimal(histoMaxValue).intValue()+1);

        titlesTab[1] = getResources().getString(R.string.history_month_histo_label);

        /* Define the Thumb URL */
        hst.setWidth(OVERVIEW_WIDTH);
        hst.setHeight(OVERVIEW_HEIGHT);
        
        chartOverviewURL[1] = hst.getURL();

        /* Define the Chart URL */
        hst.setWidth(CHART_WIDTH);
        hst.setHeight(CHART_HEIGHT);
        
        chartImageURL[1] = hst.getURL();
    }
    
    protected void showWeeklyDetailChart(){
    	for (SmokeCounter smoke : countValues){
        	detailChartData = detailChartData + "" + smoke.getValue() + Chart.DATA_SEPARATOR;
        	detailChartLabel = detailChartLabel + "" + Chart.getDayFirstLetter(this, new Integer(smoke.getLabel())) + Chart.LABEL_SEPARATOR;
        	if ( smoke.getValue() > detailsMaxValue )
        		detailsMaxValue = smoke.getValue();
    	}
        
    	/* Create the chart and define all parameters */
    	HistoChart hst = new HistoChart();
    	hst.setYAxisLabel(detailChartLabel); 
        hst.setData(detailChartData);
        hst.setMaxVal( new BigDecimal(detailsMaxValue).intValue()+1);
        hst.setBarColor("3072F3");
        titlesTab[0] = getResources().getString(R.string.history_week_detail_label);        

        /* Define the Thumb URL */
        hst.setWidth(OVERVIEW_WIDTH);
        hst.setHeight(OVERVIEW_HEIGHT);

        chartOverviewURL[0] = hst.getURL();

        /* Define the Chart URL */
        hst.setWidth(CHART_WIDTH);
        hst.setHeight(CHART_HEIGHT);
        
        chartImageURL[0] = hst.getURL();
    }
    
    protected void showWeeklyHistoryChart(){
    	
    	for (SmokeAverage smoke : averageValues){
    		histoChartData = histoChartData + "" + smoke.getValue() + Chart.DATA_SEPARATOR;
    		histoChartLabel = histoChartLabel + "" + smoke.getLabel() + Chart.LABEL_SEPARATOR;
        	if ( smoke.getValue() > histoMaxValue )
        		histoMaxValue = smoke.getValue();
    	}

    	/* Create the chart and define all parameters */
    	HistoChart hst = new HistoChart();
    	hst.setYAxisLabel(histoChartLabel); 
        hst.setData(histoChartData);
        hst.setMaxVal( new BigDecimal(histoMaxValue).intValue()+1);

        titlesTab[1] = getResources().getString(R.string.history_week_histo_label);

        /* Define the Thumb URL */
        hst.setWidth(OVERVIEW_WIDTH);
        hst.setHeight(OVERVIEW_HEIGHT);
                
        chartOverviewURL[1] = hst.getURL();

        /* Define the Chart URL */
        hst.setWidth(CHART_WIDTH);
        hst.setHeight(CHART_HEIGHT);
        
        chartImageURL[1] = hst.getURL();
    }    
    
    class ImageAdapter extends BaseAdapter {

    	private Context mContext;
    	private ImageView[] tabImgView;
    	private Drawable defaultDrawable;

    	private boolean img1UpdatedOK = false;
    	private boolean img2UpdatedOK = false;
    	private boolean loadComplete = false;

    	public ImageAdapter(Context c) {
    		mContext = c;

    		defaultDrawable = getResources().getDrawable(R.drawable.eryos);

    		tabImgView = new ImageView[2];
    		tabImgView[0] = new ImageView(mContext);
    		tabImgView[1] = new ImageView(mContext);
    		tabImgView[0].setImageDrawable(defaultDrawable);
    		tabImgView[1].setImageDrawable(defaultDrawable);
    	}

    	public View getView(final int position, View convertView, ViewGroup parent) {
    		if ( ( ( position == 0 && ! img1UpdatedOK ) || ( position == 1 && ! img2UpdatedOK ) ) && ! loadComplete ){
    			
	    		tabImgView[position] = new ImageView(mContext);
	    		thumbsTab[position] = Chart.downloadChartAsBitmap(mContext, chartOverviewURL[position]); // mImageURLs
	
	    		tabImgView[position].setImageBitmap(thumbsTab[position]);                     
	
	    		if ( position == 0 )
	    			img1UpdatedOK = true;
	    		if ( position == 1 )
	    			img2UpdatedOK = true;
	
	    		checkLoadOK();
	
	    		Log.d("getView", OVERVIEW_WIDTH+"x"+OVERVIEW_HEIGHT);
	    		tabImgView[position].setLayoutParams(new Gallery.LayoutParams(OVERVIEW_WIDTH, OVERVIEW_HEIGHT));

    		}
    		return tabImgView[position];
    	}

    	public int getCount() {
    		return chartOverviewURL.length;
    	}

    	public Object getItem(int position) {
    		return position;
    	}
    	public long getItemId(int position) {
    		return position;
    	}   

    	public void checkLoadOK(){
    		if (img1UpdatedOK && img2UpdatedOK ){
    			Log.i("checkLoad", "Both OK");
    			ia.notifyDataSetChanged();
    			hideWaitingMessage();
    		}else if ( ! img1UpdatedOK && img2UpdatedOK){
    			Log.i("checkLoad", "img 1 not OK");
    		}else if (img1UpdatedOK && ! img2UpdatedOK) {
    			Log.i("checkLoad", "img 2 not OK");
    		}
    	}
    } 
    
    /**
     * 
     * @author Olivier Combe
     */
    class ImageAdapter2 extends BaseAdapter {

    	private static final int NB_IMG = 2;

    	// Need handler for callbacks to the UI thread
        final Handler mHandler = new Handler();

        // Create runnable for posting
        final Runnable mUpdateGalleryOK = new Runnable() {
            public void run() {
            	updateImg();
            }
        };
        
        private Context mContext;
        private ImageView[] tabImgView 		= new ImageView[NB_IMG];
        private Drawable defaultDrawable;

        private boolean[] startedTab 		= new boolean[NB_IMG];
        private boolean[] downloadedTab 	= new boolean[NB_IMG];
        private boolean[] updatedTab 		= new boolean[NB_IMG];

    	public ImageAdapter2(Context c) {
            mContext = c;
            
            defaultDrawable = getResources().getDrawable(R.drawable.eryos);
            
            for (ImageView view : tabImgView ){
            	view = new ImageView(mContext);
            	view.setImageDrawable(defaultDrawable);
            }
            for ( int i = 0 ; i < NB_IMG ; i++ ){
            	updatedTab[i] 		= false;
            	downloadedTab[i] 	= false;
            	startedTab[i] 		= false;
            }
        }
    	
    	public View getView(final int position, View convertView, ViewGroup parent) {
//    		Log.d("getView", "0");		
    		
    		try {
//				if ( ( ( position == 0 && ! img1UpdatedOK ) || ( position == 1 && ! img2UpdatedOK ) ) && ! loadComplete ){
//				if ( ! downloadedTab[position] && ! updatedTab[position] && ! loadComplete /*&& ! startedTab[position]*/ ){
//    			Log.d("getView", "1");	

					Thread t = new Thread() {
						public void run() {
							Log.i("[T] getView", "Position : "+position);
//    					startedTab[position] = true;    					
							thumbsTab[position] = Chart.downloadChartAsBitmap(mContext, chartOverviewURL[position]); // mImageURLs

							tabImgView[position].setImageBitmap(thumbsTab[position]);                     
							downloadedTab[position] = true;

							mHandler.post(mUpdateGalleryOK);
						}
					};
					t.start();
				    
//        		tabImgView[position] = new ImageView(mContext);
//        		thumbsTab[position] = Chart.downloadChartAsBitmap(mContext, chartOverviewURL[position]); // mImageURLs
//        		Log.d("getView", "2");		
					
//        		tabImgView[position].setImageBitmap(thumbsTab[position]);                     
//        		Log.d("getView", "3");		
					
//        		downloadedTab[position] = true;
//        		Log.d("getView", "4");		
					
					/*if ( position == 0 )
						img1UpdatedOK = true;
					if ( position == 1 )
						img2UpdatedOK = true;
*/
					//Log.d("getView", OVERVIEW_WIDTH+"x"+OVERVIEW_HEIGHT);
					
//        		Log.d("getView", "5");		
					
					//checkLoadOK();
//        		updateImg();
//				}
			} catch (Exception e) {
				Log.e("getView", "Error", e);
			}

    		return tabImgView[position];
    	}

        public int getCount() {
            return chartOverviewURL.length;
        }

        public Object getItem(int position) {
            return position;
        }
        public long getItemId(int position) {
            return position;
        }   

        protected boolean loadComplete = false;
        
        public void updateImg(){
        	Log.d("updateImg", "0");		
    		
        	boolean res = true;
        	for ( int i = 0 ; i < NB_IMG ; i++){
        		
        		if ( downloadedTab[i] && ! updatedTab[i] ){
        			tabImgView[i].setImageBitmap(thumbsTab[i]);
        			tabImgView[i].setLayoutParams(new Gallery.LayoutParams(OVERVIEW_WIDTH, OVERVIEW_HEIGHT));
        			updatedTab[i] = true;
        		}
        		// all are TRUE
        		res = res && updatedTab[i]; 
        	}
        	Log.d("updateImg", "1");		
    		
        	if ( res ){
        		Log.i("checkLoad", "Both OK");            	
        		loadComplete = true;
            	ia.notifyDataSetChanged();
            	hideWaitingMessage();
            	Log.d("updateImg", "2");		
        		
        	}
        	Log.d("updateImg", "9");		
    		
        }
    } 
}
